# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time        : 2020/11/19 23:17
@Author      : Albert Darren
@Contact     : 2563491540@qq.com
@File        : Newtown.py
@Version     : Version 1.0.0
@Description : TODO
@Created By  : PyCharm
"""
import sympy
import numpy as np
from matplotlib import pyplot as plt


def ff(f_x, x=None):
    if x is None:
        x = list()
    if len(x) < 2:
        raise ValueError('x\'s length must be bigger than 2')
    ans = 0
    for i in range(len(x)):
        temp = 1.0
        for j in range(len(x)):
            if j == i:
                continue
            temp *= (x[i] - x[j])
        ans += (f_x[i] / temp)
    return ans


def draw(points):
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    x_range = np.linspace(-1, 1.2, 100)
    y_range = [Px.subs(sign_x, i) for i in x_range]
    y = [Px.subs(sign_x, i) for i in points]
    plt.title('4次牛顿插值多项式函数')
    plt.scatter(points, y, label="插出点", color='green')
    plt.plot(x_range, y_range, label='$P(x)$', color='red')
    plt.legend()
    plt.show()


def px(f, x_set):
    ans = f[0]
    if len(x_set) == 1:
        return ans
    else:
        temp = 1
        for i in range(len(x_set) - 1):
            temp *= (sign_x - x_set[i])
            ans += ff(f, x_set[:i + 2]) * temp
        return ans


if __name__ == '__main__':
    sign_x = sympy.symbols('x')

    x_coordinates = np.arange(0.2, 1.2, 0.2)  # 插值点横坐标
    y_coordinates = np.array([0.98, 0.92, 0.81, 0.64, 0.38])  # 插值点纵坐标
    x_points = np.array([0.08 * i + 0.2 for i in [0, 1, 10, 11]])
    Px = sympy.expand(px(y_coordinates, x_coordinates))
    draw(x_points)
